#include "const.h"

static void ignorenofiles() {
	if (!strcmp(v_getvar("goal"), ""))
		v_setvar("__int__.ignorenofiles", "yes");
}
int isignoringnofiles() {
	static int r = -1;

	if (r==-1)
		r = !strcmp(v_getvar("__int__.ignorenofiles"), "yes") ? 1 : 0;

	return r;
}

////////////////////////////////////////////////////////////////////////////////

static void showversion() {
	fprintf(stdout, "builder %s\n\n", v_getvar("builder.version"));
	fflush(stdout);

	ignorenofiles();
}

static void showhelp() {
	static const char *messages[] = {
		"mk [options] [project file...] goals",
		"",
		"OPTION              DESCRIPTION",
		"-h,--help           Show this help message",
		"-v,--version        Show BUILDER's version",
		"-V,--verbose        Be verbose",
		"--print-conf-dir    Display the configuration directory",
		"",
		"GOAL        DESCRIPTION",
		"clean       Delete all generated project binaries",
		"backup      Make a backup of all project files, except binaries",
		"debug       Incrementally build the project debug target",
		"release     Incrementally build the project release target",
		"package     Make an app-bundle (done automatically)",
		"install     Install to the device (done automatically)",
		"emulate     Run the app in the emulator",
		"test        Run the app through the device",
		"run         Run the app (tries device first, then emulator)",
		""
	};
	size_t i;

	for(i=0; i<sizeof(messages)/sizeof(messages[0]); i++)
		fprintf(stdout, "%s\n", messages[i]);

	fflush(stdout);

	ignorenofiles();
}

static void printconfdir() {
	fprintf(stdout, "%s\n", getconfigdir());
	fflush(stdout);

	ignorenofiles();
}

////////////////////////////////////////////////////////////////////////////////

static void writeline(FILE *f, const char *format, ...) {
	va_list args;

	va_start(args, format);
	vfprintf(f, format, args);
	va_end(args);

#ifdef _WIN32
	fprintf(f, "\r\n");
#else
	fprintf(f, "\n");
#endif
}
static void makedefaultbuildconf() {
	FILE *f;

	if (isfile("build.conf"))
		return;

	if (!strcmp(v_getvar("opt.verbose"), "yes")) {
		fprintf(stdout, "no configuration file specified, "
			"and build.conf doesn't exist; generating\n");
		fflush(stdout);
	}

	if (!(f = fopen("build.conf", "wb"))) {
		i_ioerror("build.conf", 0, i_errnostring());
		return;
	}

	writeline(f, "#");
	writeline(f, "#\tAUTO-GENERATED BUILD.CONF FILE");
	writeline(f, "#\tPlease refer to the documentation to learn how it works");
	writeline(f, "#");
	writeline(f, "");
	writeline(f, "# Just in case this is generated by accident...");
	writeline(f, "warn \"You are building with an auto-generated "
		"\\\"build.conf\\\"\"");
	writeline(f, "");
	writeline(f, "# Project type (executable, dynamiclib, or staticlib)");
	writeline(f, "projecttype = \"executable\"");
	writeline(f, "");
	writeline(f, "# Output name (modified based on platform and project type)");
	writeline(f, "outname = \"bin/main\"");
	writeline(f, "");
	writeline(f, "# Source directories");
	writeline(f, "srcdirs = \"src/\"");
	writeline(f, "");
	writeline(f, "# Include directories");
	writeline(f, "incdirs = \"\"");
	writeline(f, "");
	writeline(f, "# Library directories");
	writeline(f, "libdirs = \"\"");
	writeline(f, "");
	writeline(f, "# Libraries (given as space-delimited base names)");
	writeline(f, "libs = \"\"");

	fclose(f);

	if (!strcmp(v_getvar("opt.verbose"), "yes")) {
		fprintf(stdout, "finished generating build.conf\n");
		fflush(stdout);
	}
}

////////////////////////////////////////////////////////////////////////////////

int main(int argc, char **argv) {
	init(argc, argv);

	if (!strcmp(v_getvar("opt.version"), "yes"))
		showversion();

	if (!strcmp(v_getvar("opt.help"), "yes"))
		showhelp();

	if (!strcmp(v_getvar("opt.print-conf-dir"), "yes"))
		printconfdir();

	if (!strcmp(v_getvar("projectfile"), "") && !isignoringnofiles()) {
		v_setvar("projectfiles", "build.conf");
		makedefaultbuildconf();
	}

	//readdeps("source/b_close.d");

	if (!strcmp(v_getvar("projectfile"), ""))
		return 0;

	if (!v_foreach(v_var("targets"), build, (void *)0))
		return 1;

	return 0;
}

/*
	//20111109
	char buf[512];
	int i, n;

	init(argc, argv);

	fprintf(stdout, "%s\n", v_format("all args: \"$(args)\""));
	fflush(stdout);

	fprintf(stdout, "%s\n", v_format("num args: \"$(args.n)\""));
	fflush(stdout);

	n = atoi(v_format("$(args.n)"));
	for(i=0; i<n; i++) {
		fprintf(stdout, "%s\n", v_format(va("%d: \"$(args[%d])\"", i, i)));
		fflush(stdout);
	}

	fprintf(stdout, "%s\n", v_format("outfiles: $(outfiles)"));
	fflush(stdout);

	n = atoi(v_format("$(outfiles.n)"));
	for(i=0; i<n; i++) {
		fprintf(stdout, "%s\n", v_format(va("%d: \"$(outfiles[%d])\"", i, i)));
		fflush(stdout);
	}

	fprintf(stdout, "%s\n", v_format(va("outfile: $(outfile)")));
	fflush(stdout);

	fprintf(stdout, "%s\n", v_format(va("infiles: $(infiles)")));
	fflush(stdout);

	n = atoi(v_format("$(infiles.n)"));
	for(i=0; i<n; i++) {
		fprintf(stdout, "%s\n", v_format(va("%d/$(infiles.n): \"$(infiles[%d])\"", i+1, i)));
		fflush(stdout);
	}

	fprintf(stdout, "%s\n", v_format("$@, $< ($<[1]), $+, $>"));
	fflush(stdout);

	buf[0] = 0;
	i_realpath("build.conf", buf, sizeof(buf));
	fprintf(stdout, "%s\n", buf);
	fflush(stdout);

	fprintf(stdout, "config dir: \"%s\"\n", getconfigdir());
	fflush(stdout);

	fprintf(stdout, "%s\n", v_format("cpu count: $(cpucount)"));
	fflush(stdout);

	return 0;
*/
